package pl.mchaniewski.ryneczek.pojo;

// Generated Oct 3, 2011 3:17:38 AM by Hibernate Tools 3.4.0.CR1

import static javax.persistence.GenerationType.IDENTITY;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;

import pl.mchaniewski.ryneczek.utilities.DateUtil;
import pl.mchaniewski.ryneczek.utilities.I18nUtil;

@Entity
@Table(name = "orders", catalog = "stockmarket")
public class Order implements java.io.Serializable {
    private static final long serialVersionUID = -3524062454431492713L;

    private Integer orderid;
    private Portfolio portfolio;
    private Company company;
    private String transactionType;
    private BigDecimal originalPrice;
    private int amount;
    private BigDecimal setPrice;
    private int priceType;
    private int condition;
    private Date expiryDate;
    private Date submissionDate;
    private String status;

    public static final String TRANSACTION_TYPE_SELL = "SELL";
    public static final String TRANSACTION_TYPE_BUY = "BUY";
    public static final String MINIMUM_COMMISSION = "5";
    public static final String PERCENTAGE_COMMISSION = "0.39";
    public static final String STATUS_ACCEPTED = "ACCEPTED";
    public static final String STATUS_CANCELED = "CANCELED";
    public static final String STATUS_COMPLETED = "COMPLETED";
    public static final String STATUS_DENIED = "DENIED";
    public static final int PRICE_TYPE_NULL = 0;
    public static final int PRICE_TYPE_PRICE_LIMIT = 1;
    public static final int PRICE_TYPE_PKC = 2;
    public static final int PRICE_TYPE_STOP_LOSS = 3;
    public static int CONDITION_NULL = 0;

    public Order() {
    }

    public Order(Portfolio portfolio, Company company, String transactionType,
            BigDecimal originalPrice, int amount, int priceType, int condition,
            Date expiryDate, Date submissionDate, String status) {
        this.portfolio = portfolio;
        this.company = company;
        this.transactionType = transactionType;
        this.originalPrice = originalPrice;
        this.amount = amount;
        this.priceType = priceType;
        this.condition = condition;
        this.expiryDate = expiryDate;
        this.submissionDate = submissionDate;
        this.status = status;
    }

    public Order(Portfolio portfolio, Company company, String transactionType,
            BigDecimal originalPrice, int amount, BigDecimal setPrice,
            int priceType, int condition, Date expiryDate, Date submissionDate,
            String status) {
        this.portfolio = portfolio;
        this.company = company;
        this.transactionType = transactionType;
        this.originalPrice = originalPrice;
        this.amount = amount;
        this.setPrice = setPrice;
        this.priceType = priceType;
        this.condition = condition;
        this.expiryDate = expiryDate;
        this.submissionDate = submissionDate;
        this.status = status;
    }

    @Id
    @GeneratedValue(strategy = IDENTITY)
    @Column(name = "ORDERID", unique = true, nullable = false)
    public Integer getOrderid() {
        return orderid;
    }

    public void setOrderid(Integer orderid) {
        this.orderid = orderid;
    }

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "PORTFOLIOID", nullable = false)
    public Portfolio getPortfolio() {
        return portfolio;
    }

    public void setPortfolio(Portfolio portfolio) {
        this.portfolio = portfolio;
    }

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "COMPANYID", nullable = false)
    public Company getCompany() {
        return company;
    }

    public void setCompany(Company company) {
        this.company = company;
    }

    @Column(name = "TRANSACTION_TYPE", nullable = false, length = 4)
    public String getTransactionType() {
        return transactionType;
    }

    public void setTransactionType(String transactionType) {
        this.transactionType = transactionType;
    }

    @Column(name = "ORIGINAL_PRICE", nullable = false)
    public BigDecimal getOriginalPrice() {
        return originalPrice;
    }

    public void setOriginalPrice(BigDecimal originalPrice) {
        this.originalPrice = originalPrice;
    }

    @Column(name = "AMOUNT", nullable = false)
    public int getAmount() {
        return amount;
    }

    public void setAmount(int amount) {
        this.amount = amount;
    }

    @Column(name = "SET_PRICE")
    public BigDecimal getSetPrice() {
        return setPrice;
    }

    public void setSetPrice(BigDecimal setPrice) {
        this.setPrice = setPrice;
    }

    @Column(name = "PRICE_TYPE", nullable = false)
    public int getPriceType() {
        return priceType;
    }

    public void setPriceType(int priceType) {
        this.priceType = priceType;
    }

    @Column(name = "CONDITIONS", nullable = false)
    public int getCondition() {
        return condition;
    }

    public void setCondition(int condition) {
        this.condition = condition;
    }

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "EXPIRY_DATE", nullable = false, length = 19)
    public Date getExpiryDate() {
        return expiryDate;
    }

    public void setExpiryDate(Date expiryDate) {
        this.expiryDate = expiryDate;
    }

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "SUBMISSION_DATE", nullable = false, length = 19)
    public Date getSubmissionDate() {
        return submissionDate;
    }

    public void setSubmissionDate(Date submissionDate) {
        this.submissionDate = submissionDate;
    }

    @Column(name = "STATUS", nullable = false, length = 9)
    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    @Transient
    public BigDecimal getTransactionValue() {
        return getOriginalPrice().multiply(BigDecimal.valueOf(getAmount()));
    }

    @Transient
    public static final BigDecimal getTransactionValue(int amount,
            BigDecimal originalPrice) {
        return originalPrice.multiply(BigDecimal.valueOf(amount));
    }

    @Transient
    public BigDecimal getCommissionValue() {
        return getCommissionValue(getTransactionValue());
    }

    @Transient
    public static final BigDecimal getCommissionValue(
            BigDecimal transactionValue) {
        BigDecimal commissionsValue = transactionValue.multiply(
                new BigDecimal(Order.PERCENTAGE_COMMISSION)
                        .divide(new BigDecimal("100"))).setScale(2,
                RoundingMode.CEILING);

        if (commissionsValue
                .compareTo(new BigDecimal(Order.MINIMUM_COMMISSION)) != 1) {
            commissionsValue = new BigDecimal(Order.MINIMUM_COMMISSION);
        }

        return commissionsValue;
    }

    @Transient
    public BigDecimal getTotalTransactionValue() {
        return getTotalTransactionValue(getAmount(), getOriginalPrice());
    }

    @Transient
    public static final BigDecimal getTotalTransactionValue(int amount,
            BigDecimal originalPrice) {
        BigDecimal transactionVal = getTransactionValue(amount, originalPrice);
        BigDecimal commissionVal = getCommissionValue(transactionVal);

        return transactionVal.add(commissionVal);
    }

    @Transient
    public String getFormattedTransactionType() {
        if (transactionType.equals(Order.TRANSACTION_TYPE_BUY)) {
            return I18nUtil.getLocalizedMessage("order.buy");
        } else {
            return I18nUtil.getLocalizedMessage("order.sell");
        }
    }

    @Transient
    public String getFormattedPriceLimit() {
        if (setPrice != null || priceType == Order.PRICE_TYPE_PRICE_LIMIT) {
            return setPrice.toString();
        }

        switch (priceType) {
        case Order.PRICE_TYPE_PKC:
            return I18nUtil.getLocalizedMessage("order.pkc");
        case Order.PRICE_TYPE_STOP_LOSS:
            return I18nUtil.getLocalizedMessage("order.stopLoss");
        default:
            return null;
        }
    }

    @Transient
    public String getFormattedPriceType() {
        switch (priceType) {
        case Order.PRICE_TYPE_PRICE_LIMIT:
            return I18nUtil.getLocalizedMessage("order.priceLimit");
        case Order.PRICE_TYPE_PKC:
            return I18nUtil.getLocalizedMessage("order.pkc");
        case Order.PRICE_TYPE_STOP_LOSS:
            return I18nUtil.getLocalizedMessage("order.stopLoss");
        default:
            return null;
        }
    }

    @Transient
    public String getFormattedStatus() {
        if (status.equals(Order.STATUS_ACCEPTED)) {
            return I18nUtil.getLocalizedMessage("order.statusAccepted");
        }
        if (status.equals(Order.STATUS_CANCELED)) {
            return I18nUtil.getLocalizedMessage("order.statusCanceled");
        }
        if (status.equals(Order.STATUS_COMPLETED)) {
            return I18nUtil.getLocalizedMessage("order.statusCompleted");
        } else {
            return I18nUtil.getLocalizedMessage("order.statusDenied");
        }
    }

    @Transient
    public String getFormattedExpiryDate() {
        return DateUtil.simpleDateToString(expiryDate);
    }

    @Transient
    public String getFormattedArchiveExpiryDate() {
        return DateUtil.dateToString(expiryDate);
    }

    @Transient
    public String getFormattedSubmissionDate() {
        return DateUtil.simpleDateToString(submissionDate);
    }

}
